package net.sxnic.workflow.conf;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sxnic.comm.utils.CommUtils;
import net.sxnic.ugr.UgrConstant;
import net.sxnic.ugr.context.AppContext;
import net.sxnic.ugr.user.User;
import net.sxnic.ugr.utils.UgrManagerUtils;
import net.sxnic.workflow.SxnicWfException;
import net.sxnic.workflow.handler.Handler;
import net.sxnic.workflow.node.Node;
import net.sxnic.workflow.node.NodeConfig;
import net.sxnic.workflow.task.util.TaskUtils;
import net.sxnic.workflow.utils.WfManagerUtils;

import org.apache.commons.lang.StringUtils;

/**
 * 工作流转工具类数据库实现
 * @author 孙宇飞
 *
 */
public class WfConfigUtilsDbImpl implements WfConfigUtilsInterface {

	@Override
	public String findValidateDef(String processName, String nodeName) throws Exception {
		Node node = WfManagerUtils.getNodeManager().findByPdName(processName, nodeName);
		if (node == null) {
			throw new SxnicWfException("找不到相应的节点信息，获取validate定义失败");
		}
		return node.getCoeProperty("validate");
	}

	@Override
	public String findAssigneeDef(String processName, String nodeName) throws Exception {
		Node node = WfManagerUtils.getNodeManager().findByPdName(processName, nodeName);
		if (node == null) {
			throw new SxnicWfException("找不到相应的节点信息，获取assignee定义失败");
		}
		return node.getCoeProperty("assignee");
	}

	@Override
	public Set<String> findNextNodes(String processName, String nodeName) throws Exception {
		Node node = WfManagerUtils.getNodeManager().findByPdName(processName, nodeName);
		if (node == null) {
			throw new SxnicWfException("找不到相应的节点信息，获取nextNode定义失败");
		}
		String[] nodes = StringUtils.split(node.getNextNode(), ",");
		return CommUtils.ArraytoSet(nodes);
	}

	@Override
	public String findStartNodeName(String processName) throws Exception {
		return WfManagerUtils.getNodeManager().findStartNode(processName).getName();
	}

	@Override
	public String findJSP(String processName, String nodeName) throws Exception {
		Node node = WfManagerUtils.getNodeManager().findByPdName(processName, nodeName);
		if (node == null) {
			throw new SxnicWfException("找不到相应的节点信息，获取JSP定义失败");
		}
		return node.getJsp();
	}

	@Override
	public Set<String> findHandlers(String processName, String nodeName, String action) throws Exception {
		Node node = WfManagerUtils.getNodeManager().findByPdName(processName, nodeName);

		Set<String> set = new LinkedHashSet<String>();
		List<Handler> h_s = node.getHandlers();

		String handlerClass;
		String handlerAction;

		for (Handler en : h_s) {
			handlerClass = en.getClassName();
			handlerAction = en.getAction();

			if (StringUtils.isBlank(handlerAction) || StringUtils.isBlank(handlerClass)) {
				throw new Exception("handler的class属性和action属性必须有");
			}

			if (handlerAction.contains(action)) {
				set.add(handlerClass);
			}
		}

		return set;
	}

	@Override
	public String getNextAssigneeByProcessNode(String processName, String currNodeName) throws Exception {
		// set 是节点set
		Set<String> set = new LinkedHashSet<String>();
		String nodes = WfManagerUtils.getNodeManager().findByPdName(processName, currNodeName)
				.getNextNode();
		//无后续节点，返回空串
		if(StringUtils.isBlank(nodes)){
			return "";
		}
		
		set = CommUtils.ArraytoSet(StringUtils.split(nodes, ","));

		if (set == null || set.size() == 0) {
			return "";
		}

		// map内容
		// 批阅-String[]{htc,wh,qzd,wxp}
		// 承办-String[]{sgy,zhl,gjl,zkj}
		Map<String, String[]> map = new LinkedHashMap<String, String[]>();

		for (String nodeName : set) {
			map.put(nodeName, getAssigneeArrayByProcessNode(processName, nodeName));
		}

		return TaskUtils.treatMaptoNextAssignees(map);
	}

	@Override
	public String[] getAssigneeArrayByProcessNode(String processName, String nodeName) throws Exception {
		// 找到 当前node
		Node currNode = WfManagerUtils.getNodeManager().findByPdName(processName, nodeName);

		// 整合所有后续node的assignee定义
		// 用户排名 用户名的Map
		Map<String, String> assignee = new LinkedHashMap<String, String>();
		User user;

		String assigneeDef = currNode.getAssignee();

		// users:gal,sgy;groups:000,001;roles:office,docManager;special:chuanyue
		// 把上面的内容转换按分号隔开
		String[] assignee_defs = StringUtils.split(assigneeDef, ";");
		for (String a : assignee_defs) {
			// 把users:gal,sgy 分开，即把承办人类型和承办人具体定义分开处理
			String before = StringUtils.substringBefore(a, ":");
			String after = StringUtils.substringAfter(a, ":");

			// 特殊的接收人
			if (before.equals("special")) {
				//
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);
				for (String t1 : temp1) {
					if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_CHUSHI)) {						
						// 处室
						return new String[] { NodeConfig.DEFAULTASSIGNEE_CHUSHI };
					} else if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_CHUANYUE)) {
						// 传阅
						return new String[] { NodeConfig.DEFAULTASSIGNEE_CHUANYUE };
					} else if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_CHUZHANG)) {
						// 查询当前用户所在处室的 处长
						user = UgrManagerUtils.getUserManager().getChiefByUsername(AppContext.getUserName());
						// add to assignee set
						assignee.put(UgrConstant.USER_ORDER_MAP.get(user.getUsername()), user.getUsername());

					} else if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_CHUYUAN)) {
						// 当前人员所在处室
						List<User> list = UgrManagerUtils.getUserManager().getAllDeptUsersByUsername(
								AppContext.getUserName());

						// 遍历所有的处室成员包括处长
						for (User u : list) {
							// add to assignee set
							assignee.put(String.valueOf(u.getUserOrder()), u.getUsername());
						}

					} else if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_DRAFTER)) {
						// 发起人
						return new String[] { NodeConfig.DEFAULTASSIGNEE_DRAFTER};
					}
				}
			}

			if (before.equals("user")) {
				// users
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);
				// indexs
				for (String t1 : temp1) {
					user = UgrManagerUtils.getUserManager().getUserByUsername(t1);
					// add to assignee set
					assignee.put(String.valueOf(user.getUserOrder()), user.getUsername());
				}
			}
			if (before.equals("role")) {
				// roles
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);
				for (String t1 : temp1) {
					List<User> users = UgrManagerUtils.getAuthorizationManager().getUsersInRole(t1);
					for (User u : users) {
						// add to assignee set
						assignee.put(String.valueOf(u.getUserOrder()), u.getUsername());
					}
				}
			}
			if (before.equals("group")) {
				// group
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);

				for (String t1 : temp1) {
					List<User> users = UgrManagerUtils.getAuthorizationManager().getUsersInGroup(t1);
					for (User u : users) {
						// add to assignee set
						assignee.put(String.valueOf(u.getUserOrder()), u.getUsername());
					}
				}
			}

		}

		if (assignee == null || assignee.size() == 0) {
			return null;
		}

		// 排序
		String[] temp = new String[assignee.size()];
		String[] temp1 = new String[assignee.size()];

		temp = CommUtils.SettoArray(assignee.keySet());
		Arrays.sort(temp);

		int i = 0;
		for (String ss : temp) {
			temp1[i] = assignee.get(ss);
			i++;
		}

		return temp1;

	}

}
